package jp.heartdokyun.lazy;

import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import jp.heartdokyun.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;

public class ImageLoader {

	MemoryCache memoryCache = new MemoryCache();
	private Map<ImageView, Integer> imageViews = Collections
			.synchronizedMap(new WeakHashMap<ImageView, Integer>());
	ExecutorService executorService;
	private Context mContext;

	public ImageLoader(Context context) {
		mContext = context;
		executorService = Executors.newFixedThreadPool(5);
	}

	// image for loadign or no images
	final int stub_id = R.drawable.noimages;

	public void DisplayImage(int resID, ImageView imageView) {
		imageViews.put(imageView, resID);

		Bitmap bitmap = memoryCache.get(resID);
		if (bitmap != null) {
			imageView.setImageBitmap(bitmap);
		} else {
			queuePhoto(resID, imageView);
			imageView.setImageResource(stub_id);
		}
	}

	private void queuePhoto(int resID, ImageView imageView) {
		PhotoToLoad p = new PhotoToLoad(resID, imageView);
		executorService.submit(new PhotosLoader(p));
	}

	// Task for the queue
	private class PhotoToLoad {
		public int resourceID;
		public ImageView imageView;

		public PhotoToLoad(int resID, ImageView i) {
			resourceID = resID;
			imageView = i;
		}
	}

	class PhotosLoader implements Runnable {
		PhotoToLoad photoToLoad;

		PhotosLoader(PhotoToLoad photoToLoad) {
			this.photoToLoad = photoToLoad;
		}

		@Override
		public void run() {
			if (imageViewReused(photoToLoad))
				return;
			Bitmap bmp = BitmapFactory.decodeResource(mContext
					.getApplicationContext().getResources(),
					photoToLoad.resourceID);
			memoryCache.put(photoToLoad.resourceID, bmp);
			if (imageViewReused(photoToLoad))
				return;
			BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
			Activity a = (Activity) photoToLoad.imageView.getContext();
			a.runOnUiThread(bd);
		}
	}

	boolean imageViewReused(PhotoToLoad photoToLoad) {
		int tag = imageViews.get(photoToLoad.imageView);
		if (tag == 0 || tag != photoToLoad.resourceID)
			return true;
		return false;
	}

	// Used to display bitmap in the UI thread
	class BitmapDisplayer implements Runnable {
		Bitmap bitmap;
		PhotoToLoad photoToLoad;

		public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
			bitmap = b;
			photoToLoad = p;
		}

		public void run() {
			if (imageViewReused(photoToLoad))
				return;
			if (bitmap != null)
				photoToLoad.imageView.setImageBitmap(bitmap);
			else
				photoToLoad.imageView.setImageResource(stub_id);
		}
	}

	public void clearCache() {
		memoryCache.clear();
	}

}
